﻿namespace HynuIOTA.Web.Controllers
{
    using HynuIOTA.Entity.FormatEntity;
    using HynuIOTA.Web.Models;
    using System;
    using System.Collections.Generic;
    using System.Data.Entity;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Web.Caching;
    using System.Web.Mvc;
    using System.Web.UI.WebControls;
    using static HynuIOTA.Common.StringConst;

    public class HomeController : BaseController
    {
        /// <summary>
        /// GET: /Home/Index
        /// 获取主页信息
        /// TODO: 缓冲时间设置为10分钟
        /// </summary>
        /// <returns></returns>
        [OutputCache(CacheProfile = "CacheFor10Min")]
        public async Task<ActionResult> Index()
        {
            ViewBag.news = await OpContext.Service.News.Where(n => true).OrderByDescending(n => n.IsTop)
                .ThenByDescending(n => n.CreateTime).Take(10).ToListAsync();
            ViewBag.notice = await OpContext.Service.Notice.Where(n => true).OrderByDescending(n => n.CreateTime).Take(10)
                .ToListAsync();
            ViewBag.blogs = await OpContext.Service.BlogArticle.Where(b => true).OrderByDescending(b => b.WriteTime)
                .Take(10).ToListAsync();
            ViewBag.imgNews = await OpContext.Service.News.Where(n => n.IsMoveImg == true)
                .OrderByDescending(n => n.CreateTime).Take(5).ToListAsync();
            ViewBag.channel = await OpContext.Service.Channel.Where(c => c.IsDel == false && c.IsPage == false)
                .OrderByDescending(n => n.CreateTime).Take(10).ToListAsync();

            return View();
        }

        /// <summary>
        /// ANY: /Nav
        /// 加载导航条
        /// 缓冲时间为1个小时
        /// </summary>
        /// <returns></returns>
        /// TODO: 调试暂定60秒
        [OutputCache(CacheProfile = "CacheFor10Min")]
        [Route("~/Nav")]
        public async Task<ActionResult> ChannelsNav()
        {
            var channels = (await OpContext.Service.Channel.Where(c => c.IsDel == false).ToListAsync()).Select(c => new NavChannelViewModel()
            {
                Id = c.Id,
                Name = c.Name,
                Link = c.Link,
                Description = c.Description,
                Content = c.Content,
                IsPage = c.IsPage,
                ParentId = c.ParentId,
                Seq = c.Seq
            }).ToList();

            var parents = channels.Where(c => c.ParentId == null).OrderBy(c => c.Seq).ToList();
            foreach (var item in parents)
            {
                item.SonNavChannel = new List<NavChannelViewModel>();
                item.SonNavChannel.AddRange(channels.Where(c => c.ParentId == item.Id).OrderBy(c => c.Seq));
            }

            ViewBag.navs = parents;

            return View();
        }

        /// <summary>
        /// 主页底部，缓冲时间设置为10分钟
        /// </summary>
        /// <returns></returns>
        [OutputCache(CacheProfile = "CacheFor10Min")]
        [Route("~/Bottom")]
        public async Task<ActionResult> IndexBottom()
        {
            var config = await OpContext.Service.WebConfig.Where(c => true).FirstOrDefaultAsync();
            ViewBag.config = config;

            return View();
        }

        /// <summary>
        /// GET: /News
        /// 加载新闻列表
        /// </summary>
        /// <param name="page"></param>
        /// <returns></returns>
        [Route("~/News")]
        [Route("~/News/{page:int}.shtml")]
        [OutputCache(CacheProfile = "CacheFor10Min", VaryByParam = "page")]
        public async Task<ActionResult> News(int page = 1)
        {
            var pageData = new PageData
            {
                PageSize = 15,
                PageIndex = page,
                RowCount = await OpContext.Service.News.Where(n => true).CountAsync()
            };


            var news = await OpContext.Service.News.Where(n => true).OrderByDescending(n => n.IsTop).ThenByDescending(n => n.CreateTime)
                .Skip((pageData.PageIndex - 1) * pageData.PageSize)
                .Take(pageData.PageSize).ToListAsync();

            ViewBag.news = news;
            ViewBag.pageData = pageData;
            ViewBag.Title = "新闻列表";
            ViewBag.urlContent = "~/News/";

            return View();
        }

        /// <summary>
        /// GET: /Home/NewsChannelView 
        /// 获取栏目列表
        /// </summary>
        /// <returns></returns>
        [OutputCache(CacheProfile = "CacheFor10Min")]
        public async Task<ActionResult> NewsChannelView()
        {
            ViewBag.newsChannel = await OpContext.Service.Channel.Where(c => c.IsPage == false && c.IsDel == false).OrderBy(c => c.Seq).ToListAsync();

            return View();
        }

        /// <summary>
        /// GET: /Channel/
        /// 获取栏目内新闻列表
        /// </summary>
        /// <param name="id"></param>
        /// <param name="page"></param>
        /// <returns></returns>
        [Route("~/Channel/{id:int}")]
        [Route("~/Channel/{id:int}/{page=1:int}.shtml")]
        [OutputCache(CacheProfile = "CacheFor10Min", VaryByParam = "id;page")]
        public async Task<ActionResult> NewsChannel(int? id, int page = 1)
        {
            if (id == null)
            {
                return OpContext.JsBackMsg(MODEL_VALIDATE_ERROR);
            }

            var pageData = new PageData
            {
                PageSize = 15,
                PageIndex = page,
            };

            var channel = await OpContext.Service.Channel.Where(c => c.Id == id.Value).FirstOrDefaultAsync();
            pageData.RowCount = channel.News.Count;

            var news = channel.News.OrderByDescending(n => n.IsTop).ThenByDescending(n => n.CreateTime)
                .Skip((1 - page) * pageData.PageSize).Take(pageData.PageSize).ToList();

            ViewBag.pageData = pageData;
            ViewBag.news = news;
            ViewBag.Title = channel.Name;
            ViewBag.urlContent = $"~/Channel/{channel.Id}/";

            return View("~/Views/Home/News.cshtml");
        }

        public ActionResult GetCacheList()
        {
            StringBuilder sb = new StringBuilder(256);
            return Content(sb.ToString());
        }

        /// <summary>
        /// ANY: /ShowNews/
        /// 显示新闻
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [Route("~/ShowNews/{id:int}.shtml")]
        [OutputCache(CacheProfile = "CacheFor10Min", VaryByParam = "id")]
        public async Task<ActionResult> ShowNews(int? id)
        {
            if (id == null)
            {
                return OpContext.JsBackMsg(MODEL_VALIDATE_ERROR);
            }

            var news = await OpContext.Service.News.Where(ns => ns.Id == id.Value).FirstOrDefaultAsync();
            if (news == null)
            {
                return OpContext.JsBackMsg(DATA_NOEXIST_ERROR);
            }

            try
            {
                news.Click += 1;
                await OpContext.Service.SaveChangesAsync();
            }
            catch (Exception ex)
            {
                return OpContext.JsBackMsg(ex.Message);
            }

            ViewBag.news = news;
            ViewBag.Title = news.Title;

            return View();
        }

        /// <summary>
        /// ANY: /Notices
        /// 通知公告列表
        /// </summary>
        /// <param name="page"></param>
        /// <returns></returns>
        [Route("~/Notices")]
        [Route("~/Notices/{page:int}.shtml")]
        [OutputCache(CacheProfile = "CacheFor10Min", VaryByParam = "page")]
        public async Task<ActionResult> Notices(int page = 1)
        {
            var pageData = new PageData
            {
                PageSize = 15,
                PageIndex = page
            };

            var notices = await OpContext.Service.Notice.WherePage(pageData, n => true, n => n.CreateTime, false).ToListAsync();
            ViewBag.news = notices;
            ViewBag.pageData = pageData;
            ViewBag.Title = "通知列表";
            ViewBag.urlContent = "~/Notices/";

            return View();
        }

        public ActionResult LoginBar()
        {
            ViewBag.user = OpContext.UserEntity;

            return View();
        }

        /// <summary>
        /// ANY: /ShowNotice
        /// 显示通知
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [Route("~/ShowNotice/{id:int}.shtml")]
        [OutputCache(CacheProfile = "CacheFor10Min", VaryByParam = "id")]
        public async Task<ActionResult> ShowNotice(int? id)
        {
            if (id == null)
            {
                return OpContext.JsBackMsg(MODEL_VALIDATE_ERROR);
            }

            var notice = await OpContext.Service.Notice.Where(ns => ns.Id == id.Value).FirstOrDefaultAsync();
            if (notice == null)
            {
                return OpContext.JsBackMsg(DATA_NOEXIST_ERROR);
            }

            ViewBag.notice = notice;
            ViewBag.Title = notice.Title;

            return View();
        }
    }
}